--doc see http://wiki.nginx.org/HttpCoreModule#.24uri

-- 不需要认证的链接
local tabException = {
    "/",
    "/index.php",
    "/apple-app-site-association",
    "/MP_verify_nCJxLcIf4qv1JzWb.txt",

    -- 脚本和回调
    "/user/pay/exception",
    "/finance/close_an_account",
    "/room/clear_wait_close",
    "/msg/keep_alive_chat",
    "/room/rc/keep",
    "/room/rc/offline/loop",
    "/room/online/time",
    "/union/set_user_consume",
    "/finance/sync_room_wealth",
    "/room/hot/updatees",
    "/inner/roomScore/roomReputationTimer",
    "/inner/content/image/loop",
    "/inner/room/label/timingHandle",
    "/inner/room/voice/check/start/loop",
    "/inner/room/voice/check/stop/loop",
    "/inner/room/voice/check/callback",
    "/union_rank/set_wealth",
    "/union_rank/set_active_wealth",
    "/union_rank/update_contribution",
    "/union_rank/set_union_redis",
    "/inner/room/sham/user/init",
    "/inner/room/sham/loop",
    "/room/hot/loop/rank",
    "/rong_cloud_content_audit_callback",
    "/finance/pay/alipay_notify",
    "/finance/pay/alipay_h5_notify",
    "/finance/pay/wx_notify",
    "/room/rc/callback",
    "/user/rongCallback",
    "/finance/withdraw/bls/notify",
    "/finance/pay/apple_notify_verify",
    --提现回调慧用工
    "/finance/withdraw/yuque/notify",
    --提现回调 支付宝
    "/finance/withdraw/alipay/notify",
    --H5充值页面使用
    "/h5/search_uid",
    "/h5/payh5",
    "/h5/wxoauthparam",
    "/h5/wxuser/openid",
    
    --三方支付回调
    "/finance/pay/threewx_notify",
    "/finance/pay/threeali_notify",

    --cibn支付回调
    "/finance/pay/cibnali_notify",
     --微宝支付回调
    "/finance/pay/weibaoali_notify",
    "/finance/pay/weibaoali_riskControlNotifyUrl",

    --盛付通支付回调
    "/finance/pay/sftali_notify",
    --盛付通支付回调
    "/finance/pay/zftH5_notify",

        "/member/login/smscode",
	    "/member/jg/login",

    -- 微信回调
    "/weixin/mpCallback",

    -- 融云回调
    "/rongcloud/voice/callback",

    -- 融云回调
    "/rongcloud/voice/callback",

    -- 游戏回调
    "/game/get_sstoken",
    "/game/update_sstoken",
    "/game/get_user_info",
    "/game/report_game_info_url",

    -- web使用
    "/system/init",
    "/finance/withdraw/getCloudH5Url",
    "/finance/withdraw/cloudH5Notify",
    "/finance/withdraw/pay/notify",
    "/finance/withdraw/pay/notify_large",
    "/finance/query_kk_stream",
    "/finance/withdraw/rules",
    "/finance/withdraw/do",
    "/finance/withdraw/pay",
    "/finance/withdraw/apply",
    "/finance/withdraw/is_allow",
    "/finance/withdraw/getLog",
    "/finance/withdraw/getProcess",
    "/finance/withdraw/recall",
    "/finance/withdraw/getContract",
    "/finance/withdraw/dismiss",
    "/system/version/get",

    -- 统计服务
    "/analysis/stat/room/insert",

    -- 特殊设置
    "/member/verify/re_complete",
    "/member/verify/complete",

    "/finance/pay/llwx_notify",
    "/finance/pay/wx_mp_notify",
    "/finance/pay/xd_notify",
    "/finance/pay/xd_order",
    "/finance/pay/h5/auto",
    "/member/mp_login",
    "/finance/pay/rules",
    "/member/mp_info",
    "/finance/pay/wx_mp_auth_url",
    "/finance/pay/do",
    "/room/callback_addr",
    "/MP_verify_LNXu8ynIJRz454qM.txt",
    "/room/build_rank",
    "/member/remove_forbid_user",
    "/member/forbid_user",
    "/member/remove_forbid_device",
    "/member/forbid_device",
    "/member/clear_cache",
    "/system/clear_cache",
    "/member/edit",
    "/popularize/cache",
    "/system/put_file_url",
    "/msg/text",
    "/finance/pay/nologin/do",
    "/system/release_ad",
    "/system/release_version",
    "/room/hot/make",
    "/coupling/make_rank",
    "/finance/pay/userinfo/get",
    "/coupling/query_cp_value",
    "/coupling/reward_grant",
    "/finance/bank/name_list",
    "/finance/bank/bind",
    "/finance/bank/edit",
    "/finance/bank/remove",
    "/finance/bank/get",
    "/member/mp_login/check_smscode",
    "/member/verify/get_user_info",
    "/member/sms/code",
    "/activity/ranking",
    "/device/repeat",
    "/device/click",
    "/device/dadarepeat",
    "/device/dadaclick",
    "/voice/age_gender/analysis",
    "/coupling/intimate/calculation",
    "/finance/pearl/pay/rules",
    "/room/detail_info",
    "/moment/get_trends_comment_list",
    "/moment/get_trends",
    "/room/voice/check/start/loop",
    "/room/voice/check/stop/loop",
    "/room/voice/check/callback",
    "/inner/medal/grant",
    "/finance/pay/huawei_notify",
    "/meet/matching/loop",
    "/room/spanpk/runing/start",
    "/room/spanpk/match/timeout",
    "/room/spanpk/runing/stop",
    "/counter/gift/give",
    "/counter/giftpearl/give",
    "/counter/box/give",
    "/counter/gift/bag/give",
    "/counter/giftpearl/bag/give",
    "/member/invite/info",
    "/v2/external/room/micro/user_list",
    "/v2/external/room/micro/get_user_state",
    "/v2/external/user/info",
    "/v2/external/user/info_by_token",
    "/v2/external/game/duration_write",
    "/room/hot/call/stop",
    "/anonym_chat/execute_task",
    "/member/shumei/verifyCode",
    "/room/car/dissolve",
    "/finance/jianshui/payment/notify",
    "/lailai/llproject/init",
    "/lluser/verify/complete",
    "/ll/communal/init",
    "/client/verify/complete",
    "/room/open/rid",
    "/ad/timing_push",
    "/zz/global/init",
    "/consumer/verify/complete",
    "/pp/ppsystem/init",
    "/ppuser/verify/complete",
    "/v2/external/game/saolei",
    "/v2/external/game/chess5",
    "/v2/external/game/flyingChess",
    "/v2/external/game/knife",
    "/v2/external/game/painting",
    "/v2/external/game/sheep",
    "/v2/external/game/snooker",
    "/v2/external/game/guess",
    "/v2/external/game/quanquan",
    "/v2/external/room/micro/open",
    "/v2/external/room/micro/close",
    "/tt/tutusystem/init",
    "/tutuuser/verify/complete",
    "/table/poll/list",
    "/table/poll/draw",
    "/table/coupon/info",
    "/table/log/list",
    "/gift/execSkillGiftExpire",
    "/shengya/sysystem/init",
    "/syuser/verify/complete",
    "/dudu/ddsystem/init",
    "/dduser/verify/complete",
    "/finance/pay/alipay_xuwu_notify",
    "/finance/pay/wx_mp_xuwu_notify",
    "/finance/pay/wx_mp_mm_notify",
    "/finance/pay/referer",
    "/finance/pay/recharge/user",
    "/third/cooperate/access_token",
    "/third/cooperate/get/user_info",
    "/third/cooperate/get/user_assets",
    "/third/cooperate/consume/note",
    "/third/cooperate/user/follow",
    "/third/cooperate/anchor/start_live",
    "/finance/pay/wx_xuwu_notify",
    "/system/captcha_code",
    "/system/captcha_code/check",
    "/system/adjust",
    "/finance/apple/refund",
    "/test",
    "/game/truth_or_dare/wait_dealy",
    "/game/truth_or_dare/over_dealy",
    "/game/truth_or_dare/accept_dealy",
    "/user/delete_user/callback",
    "/activity/lucky_bags/callback",
    "/activity/fight_beast/grant_physical_power",
    "/meet/callback",
    "/system/service_file_upload",
    "/room/secret_room/delay_callback",
    "/room/secret_room/invite_callback",
    "/room/secret_room/reset_status_callback",
    "/monitoring_link/huawei/callback",
    "/check/recharage/getrule",
    "/check/recharage/add",
    "/advertiser/tencentClick",
    "/cool_number/delayed_callback",
    "/cool_number/be_overdue_notice",
    "/room/hot/reco_v3",
    "/room/hot/rooms3",
    "/finance/pay/union_pay_notify",
    "/advertiser/gdtClick",
    "/union/get_union_room_finance",
    "/union/get_union_consumer_user",
    "/union/show_union_room",
    "/finance/pay/alipay_huanxin_notify",
    "/finance/pay/llwx_mm_notify",
    "/union/get_union_room_finance_v2",
    "/relationship/friends/syncFriends",
    "/mq/msg/process",
    "/finance/pay/alipay_xw1102_notify",
    "/system/musicSearchAddress",
    "/system/musicSearchList",
    "/finance/pay/llwx_guagua_notify"
}



-- 直接屏蔽的guid
local blocks = {
    "pingbiguid"
}

-- 加密秘钥
local secret = "kequkweuoicw8qhikjw829f1qu2mmzpc"

local secret2 = "kequa1d538kwjf1o6ruzu65uakshqoo2"

function is_include(value, tabi)
    for k,v in ipairs(tabi) do
        if v == value then
            return true
        end
    end
    return false
end

function catch(what)
   return what[1]
end

function try(what)
   status, result = pcall(what[1])
   if not status then
      what[2](result)
   end
   return result
end


function check()
    local ok = nil
    local pid = nil
    local sig = nil
    local doc = nil
    local timestamp = 0

    local req_method = ngx.var.request_method
    local expire_time = 60 * 30

    --
    -- local secret = "821l1i1x3fv8vs3dxlj1v2x91jqfs3om"
    --
    -- heydo gen secret key for client auth
    local args = ngx.req.get_uri_args()

    -- Get auth params
    if req_method == "GET" then
        pid = ngx.var.arg_pid
        sig = ngx.var.arg__s_
        timestamp = ngx.var.arg__t_
        doc = ngx.var.arg_doc
    elseif  req_method == "POST" or req_method == "PUT" or  req_method == "DELETE" then
        try {
            function()
                ngx.req.read_body()
                local post_args = ngx.req.get_post_args()
                args = post_args
                pid = post_args.pid
                sig = post_args._s_
                timestamp = post_args._t_
                doc = post_args.doc
            end,
            catch {
                function(error)

                end
            }
        }

        if not sig then
            sig=ngx.var.arg__s_
        end

        if not timestamp then
            timestamp = ngx.var.arg__t_
        end

        if not doc then
            doc = ngx.var.arg_doc
        end

    elseif req_method == "OPTIONS" then
        ngx.header["Access-Control-Allow-Origin"] = "*"
        ngx.header["Access-Control-Allow-Methods"] = "POST,GET,OPTIONS,DELETE"
        ngx.header["Access-Control-Allow-Headers"] = "Origin, Authorization, H5-User-Agent, Requested-Token, X-Requested-With, Content-Type, Accept,Noaes, WG-App-Version, WG-Device-Id, WG-Network-Type, WG-Vendor, WG-OS-Type, WG-OS-Version, WG-Device-Model, WG-CPU, WG-Sid, WG-App-Id, WG-Token, XMLHttpRequest, access-control-allow-origin"
        ngx.header["Access-Control-Allow-Credentials"] = "true"
        ngx.header["Content-Type"] = "application/json;charset=utf-8"
        ngx.exit(ngx.HTTP_OK)
    else
        ngx.exit(ngx.HTTP_FORBIDDEN)
    end

    -- ***** doc debug *****
    if doc then
        return
    end

    if not timestamp or timestamp == ""  then
        ngx.exit(ngx.HTTP_FORBIDDEN)
    end

    if not sig or sig == "" then
        ngx.exit(ngx.HTTP_FORBIDDEN)
    end


    local filter_args = ""
    local key_table = {}
    --取出所有的键
    for key,_ in pairs(args) do
        table.insert(key_table,key)
    end
    --对所有键进行排序
    table.sort(key_table)
    for _,key in pairs(key_table) do
        if key ~= "_s_"  and key ~= "_t_"  then
            filter_args = filter_args .. key .. "=" ..args[key]
        end
    end

    for _, value in pairs(blocks) do
        block = string.match(filter_args,value)
        if block then
            ngx.exit(ngx.HTTP_FORBIDDEN)
        end
    end

    -- the request is expired
    if ngx.now() - timestamp < -expire_time or ngx.now() - timestamp >= expire_time then
        ngx.status = ngx.HTTP_GONE
        local _now = ngx.now()
        ngx.header.server_time = _now
        ngx.say(_now)
        ngx.exit(ngx.HTTP_OK)
    end

    -- generate signature
    token_string = req_method .. ":" .. ngx.var.uri .. ":" .. filter_args .. ":" .. timestamp .. ":"  .. secret

    --ngx.log(ngx.ERR, token_string)
    token = ngx.md5(token_string)

    -- generate signature
    token_string2 = req_method .. ":" .. ngx.var.uri .. ":" .. filter_args .. ":" .. timestamp .. ":"  .. secret2

    --ngx.log(ngx.ERR, token_string)
    token2 = ngx.md5(token_string2)

    -- ngx.log(ngx.ERR, token)

    -- Compare sever genned sig(var token) with request sig(request param sig)
    if token ~= sig then
        if token2 ~= sig then
            ngx.exit(ngx.HTTP_FORBIDDEN)
        else
            return
        end
    else
        return
    end
end

local is_exist = is_include(ngx.var.uri, tabException)

if not is_exist then
    check()
end


